{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "# neural network（神经网络）\n",
    "\n",
    "使用逻辑回归识别手写数字。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 64,
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import pandas as pd\n",
    "import matplotlib\n",
    "import matplotlib.pyplot as plt\n",
    "# 提供了各种优化算法\n",
    "import scipy.optimize as opt\n",
    "# 用于读取和写入各种数据文件格式\n",
    "from scipy.io import loadmat\n",
    "# 用于生成分类模型的评估报告，包括精确度、召回率、F1值等指标\n",
    "from sklearn.metrics import classification_report"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "## 训练集\n",
    "一共5000个训练数据，每个数据是一个表示20*20的灰度图像即400维，总的矩阵为5000*400。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 65,
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [],
   "source": [
    "# 当transpose为True时，表示加载的数据将会被转置\n",
    "def load_data(path, transpose=True):\n",
    "    data = loadmat(path)\n",
    "    X = data['X']\n",
    "    y = data['y']\n",
    "    # y.shape[0]获取到y的第一个维度的大小（通常是样本数量），然后使用reshape()函数将y重新调整为一个一维数组。\n",
    "    y = y.reshape(y.shape[0])\n",
    "    print(type(X))\n",
    "    if transpose:\n",
    "        # 代码中的循环遍历了数组X中的每个元素im，其中X是一个多维数组。对于每个元素im，它首先被重新调整形状为(20, 20)，然后通过.T进行转置操作，使得行变为列，列变为行。最后，通过.reshape(400)将转置后的二维数组重新展平为一维数组，长度为400。\n",
    "        X = np.array([im.reshape((20,20)).T.reshape(400) for im in X])\n",
    "    return X, y"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 66,
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'numpy.ndarray'>\n"
     ]
    },
    {
     "data": {
      "text/plain": "((5000, 400), (5000,))"
     },
     "execution_count": 66,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "raw_x, raw_y = load_data('ex3data1.mat')\n",
    "raw_x.shape, raw_y.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 67,
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [],
   "source": [
    "def plot_an_image(image):\n",
    "    fig, ax = plt.subplots(figsize=(1, 1))\n",
    "    # 使用ax.matshow()方法将调整后的二维数组作为图像绘制在坐标轴上。cmap=matplotlib.cm.binary参数指定了图像的颜色映射为二值图像，即黑白灰度图像。\n",
    "    ax.matshow(image.reshape((20,20)), cmap=matplotlib.cm.binary)\n",
    "    # 通过plt.xticks(np.array([]))和plt.yticks(np.array([]))将x轴和y轴的刻度设置为空，这样可以去除坐标轴的刻度标签\n",
    "    plt.xticks(np.array([]))\n",
    "    plt.yticks(np.array([]))\n",
    "    plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 68,
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": "<Figure size 100x100 with 1 Axes>",
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAGUAAABqCAYAAAClKp8aAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMywgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/NK7nSAAAACXBIWXMAAA9hAAAPYQGoP6dpAAAE+0lEQVR4nO2du0srQRTGJ75fMWIlIYKPxogvsFAUsbARG7UTERtbQVCwsdDaUrAQxcZHYacoiI3/gaig0U5MDGKj2QXfJrdy2XO8m5i9G++J+X7VfJwkbvJ55szOzO66YrFYTAFRZP3vAwBfgSkCgSkCgSkCgSkCgSkCgSkCgSkCgSkCgSkCgSkCgSkCybH7xmg0qsLhsHK73crlcjl5TL+WWCymdF1XXq9XZWVZ54NtU8LhsKqsrLT79owmGAwqn89nGbdtitvtVkopFQgEjDaIj67ryu/3J/y9bJvy2WW53W5VWlpq92MykkTdPQq9QGxnijTM/305Oc5+Lb44+/HxYRlzAmSKQGCKQGCKQNK2pvARjLmfPz4+JjFd1y1fq5RSFxcXRFdUVBDd0tJCdHV1teVxOVFjkCkCgSkCgSkCSduakp2dTfTR0ZHR7u/vJzFN04jmk4HRaDRuvLa2luiZmRmjPTg4SGK81tmpMcgUgcAUgaRt98W7HK/Xa7QnJiZIjE+YPj8/E/309ET06ekp0QcHB0Tv7u4a7b6+PhIrKCggGt3XLwGmCASmCORX1pTp6WkSSzRM5UPgUChEdFdXF9HX19dG+/HxkcQKCwvjHfa3QKYIBKYIBKYIJG1rCsc8HZ9oY0KiGrO0tET0w8MD0W1tbUa7pKQk7mfZAZkiEJgiEJgikF9TU8zwfp3XEL4FaXFxMa7mW0yHh4eNdnFxMYm9vLwkd7B/AZkiEJgiEJgiELE1JdlrXuKdH/A1Dr4+sr6+TjSvC+Pj40TX19cb7dfX16SO8zsgUwQCUwQCUwQipqbwNQ2uE80pmc898vLySGx1dZXoubk5om9uboienJwkemxsjGhzvePrOk6ATBEITBHIf+u++FQHH4aat/EopdT5+TnRRUVFRDc2NhptviNyYWGB6GAwSPTIyAjRfDmZ78Z8f39XqQSZIhCYIhCYIpAfrSnmOnJ1dUViy8vLRG9sbBB9f39PNO/nzZ/Nr9Tiw+mBgQGiZ2dniS4rKyPaien4ZECmCASmCASmCCSlNSU3N5do8/nB/Pw8ie3s7BDd3d1NNL8i9/DwkOizszOjHe+2TX+DXwoRDoeJ5tuI8vPzjTbuOJEhwBSBwBSBOFpTeF/Ox/crKytGe3Nzk8Sam5uJbmhoIHptbY3o29tby9e3traS2P7+PtHb29tE7+3tEV1XV0f01NQU0UNDQ0Yby8EZAkwRCEwRSEpryt3dHdFbW1uWrw0EAkSfnJwQzS9b43d6MG8DMq+tKEVrgFJfz3H4cjCf+2pqaiKaz605DTJFIDBFIDBFII7WFL7dxuPxEN3b22u0+dZRPr9UU1NDdE9PD9Gjo6NEm+fZ+HF0dnYS3d7eTjSvEbzexbsLXypApggEpggEpgjEZffZwZqmKY/Ho0KhkOW97vk6eiQSMdqXl5ckVl5eTnRVVRXR5jUMpZR6e3sjOpmv4eRlFsmgaZry+XwqEonEfT4AMkUgMEUgKV0O5kNHc8p2dHSQGB/G8q2hTk6RS3/aOzJFIDBFIDBFID+6bdVcN356K2g6gUwRCEwRCEwRCEwRCEwRCEwRiO0h8edUBX/eFbDm87dKeKOGf/0Dfr/f7kdkLLquf1kqN2N7PQWPPk+e7z763LYpIHWg0AsEpggEpggEpggEpggEpggEpggEpggEpggEpggEpggEpgjkD4vMgJ/5DYCaAAAAAElFTkSuQmCC\n"
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "this should be 2\n"
     ]
    }
   ],
   "source": [
    "# random.randint()函数从0到5000（不包括5000）之间随机生成一个整数，并将结果赋值给变量pick_one\n",
    "pick_one = np.random.randint(0, 5000)\n",
    "plot_an_image(raw_x[pick_one, :])\n",
    "print('this should be {}'.format(raw_y[pick_one]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 69,
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [],
   "source": [
    "def sigmoid(z):\n",
    "    return 1 / (1 + np.exp(-z))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "## 准备数据\n",
    "\n",
    "![](img/向量化标签.png)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 70,
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": "(5000, 401)"
     },
     "execution_count": 70,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 在raw_x数组的列维度上插入一列全为1的数组，并将结果赋值给变量X\n",
    "X = np.insert(raw_x, 0, np.ones(raw_x.shape[0]), axis=1)\n",
    "X.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 97,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(10, 5000)\n",
      "(5000,)\n"
     ]
    }
   ],
   "source": [
    "y = []\n",
    "for k in range(1, 11):\n",
    "    # 对于raw_y中的每个元素，如果元素的值等于k，则在对应位置插入1，否则插入0。最终得到的列表作为一个新的行添加到y列表中\n",
    "    y.append([1 if i==k else 0 for i in raw_y])\n",
    "y = np.array([y[-1]] + y[:-1])\n",
    "print(y.shape)\n",
    "print(y[0].shape)"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 72,
   "outputs": [
    {
     "data": {
      "text/plain": "array([[1, 1, 1, ..., 0, 0, 0],\n       [0, 0, 0, ..., 0, 0, 0],\n       [0, 0, 0, ..., 0, 0, 0],\n       ...,\n       [0, 0, 0, ..., 0, 0, 0],\n       [0, 0, 0, ..., 0, 0, 0],\n       [0, 0, 0, ..., 1, 1, 1]])"
     },
     "execution_count": 72,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "## 代价函数\n",
    "![](img/cost.png)"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%% md\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 73,
   "outputs": [],
   "source": [
    "def cost(theta, X, y):\n",
    "    first = y * np.log(sigmoid(X @ theta.T))\n",
    "    second = (1 - y) * np.log(1 - sigmoid(X @ theta.T))\n",
    "    return -np.mean(first + second)"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 74,
   "outputs": [],
   "source": [
    "def regularized_cost(theta, X, y, l):\n",
    "    reg = l / (2 * len(X)) * (theta[1:] ** 2).sum()\n",
    "    return cost(theta, X, y) + reg"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "## 梯度函数\n",
    "![](img/gradient.png)\n"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%% md\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 75,
   "outputs": [],
   "source": [
    "def gradient(theta, X, y, l):\n",
    "    error = sigmoid(X@theta.T) - y\n",
    "    grad = X.T @ error / len(X)\n",
    "    reg = theta * l / len(X)\n",
    "    reg[0] = 0\n",
    "    return grad + reg"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 76,
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [],
   "source": [
    "def logistic_regression(X, y, l=1):\n",
    "    theta = np.zeros(X.shape[1])\n",
    "    res = opt.minimize(fun = regularized_cost, x0=theta, args=(X, y, l), method='TNC', jac=gradient, options={'disp': True})\n",
    "    # 返回优化后的参数值\n",
    "    return res.x"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "## 预测分析"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 77,
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [],
   "source": [
    "def predict(theta, X):\n",
    "    prob = sigmoid(X @ theta)\n",
    "    return [1 if i >= 0.5 else 0 for i in prob]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "训练1维"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 78,
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": "(401,)"
     },
     "execution_count": 78,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "theta_0 = logistic_regression(X, y[0])\n",
    "theta_0.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 79,
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Accurary = 0.9974\n"
     ]
    }
   ],
   "source": [
    "y_pred = predict(theta_0, X)\n",
    "print('Accurary = {}'.format(np.mean(y[0] == y_pred)))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "训练k维"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 80,
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": "(10, 401)"
     },
     "execution_count": 80,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "theta_k = np.array([logistic_regression(X, y[k]) for k in range(10)])\n",
    "theta_k.shape"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "X：(5000, 401)\n",
    "\n",
    "y：(10, 5000)\n",
    "\n",
    "theta_k：(10,401)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 81,
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": "array([[0.99577261, 0.        , 0.00053482, ..., 0.00006469, 0.00003913,\n        0.00172218],\n       [0.99834581, 0.0000001 , 0.00005607, ..., 0.00009674, 0.0000029 ,\n        0.00008487],\n       [0.99139784, 0.        , 0.00056859, ..., 0.00000655, 0.02653656,\n        0.0019755 ],\n       ...,\n       [0.00000068, 0.04138728, 0.00321014, ..., 0.00012718, 0.00297371,\n        0.70758953],\n       [0.00001841, 0.00000013, 0.00000009, ..., 0.0016486 , 0.06816333,\n        0.86116834],\n       [0.02880799, 0.        , 0.00012979, ..., 0.36620358, 0.00497419,\n        0.14824908]])"
     },
     "execution_count": 81,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "prob_matrix = sigmoid(X @ theta_k.T)\n",
    "# suppress=True的作用是抑制科学计数法的输出，将小数显示为常规的十进制形式。\n",
    "np.set_printoptions(suppress=True)\n",
    "prob_matrix"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 82,
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": "array([10, 10, 10, ...,  9,  9,  7], dtype=int64)"
     },
     "execution_count": 82,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 返回每行最大值对应的列索引\n",
    "y_pred = np.argmax(prob_matrix, axis=1)\n",
    "# 将预测结果中的索引0替换为类别10，其余的索引保持不变，得到最终的预测结果 y_pred。\n",
    "y_pred = np.array([10 if i == 0 else i for i in y_pred])\n",
    "y_pred"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 83,
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "              precision    recall  f1-score   support\n",
      "\n",
      "           1       0.95      0.99      0.97       500\n",
      "           2       0.95      0.92      0.93       500\n",
      "           3       0.95      0.91      0.93       500\n",
      "           4       0.95      0.95      0.95       500\n",
      "           5       0.92      0.92      0.92       500\n",
      "           6       0.97      0.98      0.97       500\n",
      "           7       0.95      0.95      0.95       500\n",
      "           8       0.93      0.92      0.92       500\n",
      "           9       0.92      0.92      0.92       500\n",
      "          10       0.97      0.99      0.98       500\n",
      "\n",
      "    accuracy                           0.94      5000\n",
      "   macro avg       0.94      0.94      0.94      5000\n",
      "weighted avg       0.94      0.94      0.94      5000\n",
      "\n"
     ]
    }
   ],
   "source": [
    "print(classification_report(raw_y, y_pred))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "# 神经网络\n",
    "\n",
    "![](img/nn_model.png)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "## 前向传播\n",
    "\n",
    "已经给出训练得到的theta1,theta2，通过前向传播计算得到预测结果"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 84,
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [],
   "source": [
    "def load_weight(path):\n",
    "    data = loadmat(path)\n",
    "    return data['Theta1'], data['Theta2']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 85,
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": "((25, 401), (10, 26))"
     },
     "execution_count": 85,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "theta1, theta2 = load_weight('ex3weights.mat')\n",
    "theta1.shape, theta2.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 86,
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'numpy.ndarray'>\n"
     ]
    },
    {
     "data": {
      "text/plain": "((5000, 401), (5000,))"
     },
     "execution_count": 86,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "X, y = load_data('ex3data1.mat', transpose=False)\n",
    "X = np.insert(X, 0, np.ones(X.shape[0]), axis=1)\n",
    "X.shape, y.shape"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "输入层"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 87,
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [],
   "source": [
    "a1 = X"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 88,
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": "(5000, 26)"
     },
     "execution_count": 88,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "z2 = a1 @ theta1.T\n",
    "z2 = np.insert(z2, 0, np.ones(z2.shape[0]), axis=1)\n",
    "z2.shape"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "第二层"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 89,
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": "(5000, 26)"
     },
     "execution_count": 89,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a2 = sigmoid(z2)\n",
    "a2.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 90,
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": "(5000, 10)"
     },
     "execution_count": 90,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "z3 = a2 @ theta2.T\n",
    "z3.shape"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "输出层"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 91,
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": "(5000, 10)"
     },
     "execution_count": 91,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a3 = sigmoid(z3)\n",
    "a3.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 92,
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": "array([[0.00013825, 0.0020554 , 0.00304012, ..., 0.00049102, 0.00774326,\n        0.99622946],\n       [0.00058776, 0.00285027, 0.00414688, ..., 0.00292311, 0.00235617,\n        0.99619667],\n       [0.00010868, 0.0038266 , 0.03058551, ..., 0.07514539, 0.0065704 ,\n        0.93586278],\n       ...,\n       [0.06278247, 0.00450406, 0.03545109, ..., 0.0026367 , 0.68944816,\n        0.00002744],\n       [0.00101909, 0.00073436, 0.00037856, ..., 0.01456166, 0.97598976,\n        0.00023337],\n       [0.00005908, 0.00054172, 0.0000259 , ..., 0.00700508, 0.73281465,\n        0.09166961]])"
     },
     "execution_count": 92,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a3"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 93,
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": "array([10, 10, 10, ...,  9,  9,  9], dtype=int64)"
     },
     "execution_count": 93,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 返回沿着第一个轴（行轴）的最大值的索引\n",
    "y_pred = np.argmax(a3, axis=1)+1\n",
    "y_pred"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 94,
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "              precision    recall  f1-score   support\n",
      "\n",
      "           1       0.97      0.98      0.97       500\n",
      "           2       0.98      0.97      0.97       500\n",
      "           3       0.98      0.96      0.97       500\n",
      "           4       0.97      0.97      0.97       500\n",
      "           5       0.98      0.98      0.98       500\n",
      "           6       0.97      0.99      0.98       500\n",
      "           7       0.98      0.97      0.97       500\n",
      "           8       0.98      0.98      0.98       500\n",
      "           9       0.97      0.96      0.96       500\n",
      "          10       0.98      0.99      0.99       500\n",
      "\n",
      "    accuracy                           0.98      5000\n",
      "   macro avg       0.98      0.98      0.98      5000\n",
      "weighted avg       0.98      0.98      0.98      5000\n",
      "\n"
     ]
    }
   ],
   "source": [
    "print(classification_report(y, y_pred))"
   ]
  }
 ],
 "metadata": {
  "anaconda-cloud": {},
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}